#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>

bool serialize(const Json::Value &val, std::string &body){
    std::stringstream ss;

    // 先实例化一个工厂类对象
    Json::StreamWriterBuilder swb;
    // 禁用 Unicode 转义，以便直接输出UTF-8字符（如汉字）
    swb["emitUTF8"] = true;
    // 通过工厂类对象来实例化派生类序列化对象
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

    int ret = sw->write(val, &ss);
    if (ret != 0){
        std::cerr << "serialize error..." << std::endl;
        return false;
    }
    
    body = ss.str();
    return true;
}

bool unserialize(const std::string &body, Json::Value &val){
    std::string errs;

    // 先实例化工厂类对象
    Json::CharReaderBuilder crb;
    // 通过工厂类对象来实现话反序列化派生类对象
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

    bool ret = cr->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
    if (ret == false){
        std::cerr << "unserialize error... failed: " << errs << std::endl;
        return false;
    }
    return true;
}

int main(){
    // 实例化一个Json::Value对象
    Json::Value stu;
    stu["姓名"] = "张三";
    stu["年龄"] = 18;
    stu["性别"] = "男";
    stu["成绩"].append(80);
    stu["成绩"].append(90);
    stu["成绩"].append(100);
    // 也可以嵌套对象
    Json::Value hobby;   
    hobby["爱好"].append("游戏");
    hobby["爱好"].append("篮球");
    stu["个人爱好"] = hobby;

    // 序列化
    std::string body;
    bool ret = serialize(stu, body);
    if(!ret){
        return 1;
    }
    std::cout << body << std::endl;

    // 反序列化
    Json::Value val;
    ret = unserialize(body, val);
    if(!ret){
        return 2;
    }

    std::cout << val["姓名"].asString() << std::endl;
    std::cout << val["年龄"].asInt() << std::endl;
    std::cout << val["性别"].asString() << std::endl;
    for (int i = 0; i < val["成绩"].size(); i++){
        std::cout << val["成绩"][i].asFloat() << std::endl;
    }
    std::cout << val["个人爱好"]["爱好"][0].asString() << std::endl;
    std::cout << val["个人爱好"]["爱好"][1].asString() << std::endl;

    return 0;
}